package tool

import (
	"GoServer/utils/debug"
	"bytes"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	LiveComment = "live_comment"
	LiveGift    = "live_gift"
	LiveLike    = "live_like"
)

/**
* 可进行重试的http-post请求方法
* attempts 重试次数
* sleepTime 重试间隔时间 如1为1秒
* postUrl 发送请求的路由
* reqBody 请求参数
 */
func SendPostRetry(attempts int, sleepTime time.Duration, postUrl string, reqBody string, headers map[string]string) ([]byte, error) {
	errString := ""
	for index := 0; index < attempts; index++ {
		res, err := sendHttpRequest("POST", postUrl, reqBody, headers)
		if err == nil {
			return res, nil
		}
		if index != 0 {
			errString += "|" + err.Error()
		} else {
			errString += err.Error()
		}
		time.Sleep(sleepTime * time.Duration(2*index+1))
	}

	return nil, errors.New("SendRetry err:" + errString)
}

/**
* 单次的http_post 请求方法
* postUrl 发送请求的路由
* reqBody 请求参数
 */
func SendPostOnceRetry(postUrl string, reqBody string, headers map[string]string) ([]byte, error) {
	debug.Logln(debug.Debug, "post Url: ", postUrl)
	debug.Logln(debug.Debug, "Request Body: ", reqBody)
	res, err := sendHttpRequest("POST", postUrl, reqBody, headers)

	if err != nil {
		return nil, err
	}

	debug.Logln(debug.Debug, "Post 返回结果 : ", string(res))
	return res, nil
}

/**
* 单次的http_get 请求方法
* postUrl 发送请求的路由
* reqBody 请求参数
 */
func SendGetRetry(postUrl string, reqBody string, headers map[string]string) ([]byte, error) {
	debug.Logln(debug.Info, "get Url", postUrl)
	res, err := sendHttpRequest("GET", postUrl, reqBody, headers)

	if err != nil {
		return nil, err
	}

	return res, nil
}

// 可进行重试的http-post请求方法
func sendHttpRequest(method, postUrl string, reqBody string, headers map[string]string) ([]byte, error) {
	client := &http.Client{
		Transport: &http.Transport{
			DialContext: (&net.Dialer{
				Timeout:   2 * time.Second,
				KeepAlive: 2 * time.Second,
			}).DialContext,
			ResponseHeaderTimeout: 2 * time.Second,
		},
		Timeout: 5 * time.Second, // 可选全局 timeout
	}

	req, err := http.NewRequest(method, postUrl, strings.NewReader(reqBody))
	if err != nil {
		debug.Logf(debug.Error, fmt.Sprintf("NewRequest error: %v", err))
		return nil, fmt.Errorf("http request creation failed: %w", err)
	}

	for key, value := range headers {
		debug.Logf(debug.Debug, fmt.Sprintf("[http][request header] : [key : %s], [value : %s]", key, value))
		req.Header.Set(key, value)
	}

	res, err := client.Do(req)
	if err != nil {
		debug.Logf(debug.Error, fmt.Sprintf("httpPost error: %v, url: %v, params: %v", err, postUrl, reqBody))
		return nil, fmt.Errorf("http do failed: %w", err)
	}
	defer res.Body.Close()

	data, err := io.ReadAll(res.Body)
	if err != nil {
		debug.Logf(debug.Error, "ReadAll error: %v", err)
		return nil, fmt.Errorf("read body failed: %w", err)
	}

	return data, nil
}

func SendHttpRequest(method, baseURL string, query map[string]string, body string, headers map[string]string) ([]byte, error) {
	// 拼接 query 参数
	if len(query) > 0 {
		q := url.Values{}
		for k, v := range query {
			q.Set(k, v)
		}
		if strings.Contains(baseURL, "?") {
			baseURL += "&" + q.Encode()
		} else {
			baseURL += "?" + q.Encode()
		}
	}
	debug.Logln(debug.Info, fmt.Sprintf("请求参数：%s", baseURL))
	// 构建请求对象
	req, err := http.NewRequest(method, baseURL, bytes.NewBufferString(body))
	if err != nil {
		return nil, fmt.Errorf("create request failed: %w", err)
	}

	// 添加 header
	for k, v := range headers {
		req.Header.Set(k, v)
	}

	// 构建 client 并发请求
	client := &http.Client{
		Timeout: 5 * time.Second,
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("http request failed: %w", err)
	}
	defer resp.Body.Close()

	resBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read response failed: %w", err)
	}

	// 非 2xx 也可以根据需求做判断
	if resp.StatusCode >= 400 {
		return nil, errors.New(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(resBody)))
	}

	return resBody, nil
}
